/**
 * 
 */
package Vector;

import java.util.Iterator;
import java.util.Random;
import java.util.Vector;

/**
 * @author steven.e.suit
 *  Purpose: Exam II Question 1: Implement the Vector union method
 * 	so that the returned Vector is a set all elements excluding 
 *	duplicates 
 */
public class vector {

	// Empty Vector provided
	private static final String EMPTY_VECTOR = "Provided Vector is empty: ";
	
	// Invalid Vector provided
	private static final String INVALID_VECTOR = "Invalid Vector provided: ";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
	
		try {
			// Initialize the two Vectors 'a' and 'b' with some numbers
			Vector<Integer> a = new Vector<Integer>();
			Vector<Integer> b = new Vector<Integer>();
			a = initialize();
			b = initialize();
			
			// Perform the union of the two Vectors
			Vector<Integer> c = new Vector<Integer>();
			c = union(a, b);
			
			// Print the original Vectors
			printVector("Vector a: ", a);
			printVector("Vector b: ", b);
			
			// Print the result Vector
			if ( c.isEmpty() ) {
				printVector("Result of a U b is an empty set ", c);
			} else {
				printVector("Result of a U b: ", c);
			}
		} catch (Exception msg) {
			System.out.println("** ERROR: msg **");
		}
	}
	
	/**
	 * This will return the result set of a union between 'a' and 'b'
	 * Precondition The Vectors are initialized with Integers
	 * @param a First Vector
	 * @param b Second Vector
	 * @return result
	 * @throws Exception if either of the provided Vectors are empty
	 */
	public static Vector<Integer> union(Vector<Integer> a, Vector<Integer> b) throws Exception {		
		// Make sure the provided Vectors are valid
		if ( a == null || !isValid(a) )
			throw new Exception(INVALID_VECTOR + "a");

		// Make sure the provided Vectors are valid
		if ( b == null || !isValid(b))
			throw new Exception(INVALID_VECTOR + "b");
		
		// The result Vector
		Vector<Integer> result = new Vector<Integer>();
		
		// Will hold the next value
		int nextInt;
		
		// The iterator for the Vector
		Iterator<Integer> iter = a.iterator();
		
		// Iterate through the first Vector adding new elements
		while(iter.hasNext()) {
			// If the result Vector is empty, add the element
			if ( result.isEmpty() ) {
				result.add(iter.next());
			} else {
				// If the result Vector is not empty, check to make sure
				// it does not already exist in the list
				nextInt = iter.next();
				if ( !result.contains(nextInt) ) {
					result.add(nextInt);
				}
			}
		}
		
		iter = b.iterator();
		// Iterate through the second Vector adding new elements
		while(iter.hasNext()) {
			nextInt = iter.next();
			if ( !result.contains(nextInt) ) {
				result.add(nextInt);
			}
		}
		
		return result;
	}

	/**
	 * This will randomly generate values Vector fill the Vectors 'a' and 'b'
	 * @return the filled Vector
	 * @throws Exception when the Vector is empty
	 */
	private static Vector<Integer> initialize() throws Exception {
		Vector<Integer> tmp = new Vector<Integer>();
		// Generate a random number limit of numbers for the Vector
		// from size 1 - 10
		Random generator = new Random();
		int limit = generator.nextInt(10) + 1;
		
		// Randomly generate numbers to fill Vector from 0 - 9
		for (int i = 0; i < limit; i++)
			tmp.add(generator.nextInt(10));
		
		if ( tmp == null || tmp.isEmpty() )
			throw new Exception(EMPTY_VECTOR + "tmp");

		return tmp;
	}

	/**
	 * This will iterate through the Vector 'z' to make sure all values are
	 * Integers
	 * @param z Provided Vector
	 * @return true if all values are Integers, false if at least one is not
	 */
	private static boolean isValid(Vector<Integer> z) {
		
		try {
			Iterator<Integer> iter = z.iterator();
			while ( iter.hasNext() ) {
				Integer.parseInt(iter.next().toString()); 
			}
		} catch (Exception e) {
			return false;
		}
		
		return true;
	}
	
	/**
	 * Print the Vector z along side the provided String
	 * @param z The provided Vector
	 * @param str The provided String
	 * @throws Exception if the Vector is empty
	 */
	private static void printVector(String str, Vector<Integer> z) throws Exception {		
		if ( z == null)
			throw new Exception(INVALID_VECTOR + "z");
		
		System.out.println(str + z);
	}
}